package org.xml.xpath4js.client;

/* 
xpath4js is a GWT implementation of XPath 2.0 
Copyright (C) 2010  Peter Schonefeld (peter dot schonefeld at gmail)

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

import java.util.Iterator;
import java.util.Vector;
import java.util.HashMap;

@SuppressWarnings("unchecked")
public class EvalEngine {
	public static Integer XPATH_NUM_KNOWN_BASIC_TOKENS = 40;
	public static Integer XPATH_MAX_PATTERN_LOOKAHEAD = 3;	
	
	//start here	
	public static XPathSequence DoXPath(XPathSequence pInput, String sExpr){
		XPathSequence result = new XPathSequence();
		XPathStaticEnv SE = new XPathStaticEnv();
		XPathDynamicEnv DE = new XPathDynamicEnv(SE, pInput, result);
		EvalEngine EE = new EvalEngine(SE, DE, pInput, result);
		EE.ParseExpression(sExpr);
		if(!EE.IsInError){
			result = EE.Evaluate(EE.ExprTree,pInput);
		}
		else {
			result.AppendItem(new XPathItem(EE.ErrorMsg, "Error"));
		}
		
		return result;
	}
	public XPathStaticEnv StatEnv = new XPathStaticEnv();
	public XPathDynamicEnv DynamicEnv = new XPathDynamicEnv();
	public XPathSequence Input = new XPathSequence(); 
	public XPathSequence Result = new XPathSequence();
	
	public EvalEngine(){
		this.Init();
	};
	
	public EvalEngine(XPathStaticEnv statEnv, 
				XPathDynamicEnv dynEnv, 
				XPathSequence input, 
				XPathSequence result){
		this.StatEnv = statEnv; 
		this.DynamicEnv = dynEnv;
		this.Input = input;
		this.Result = result;
		this.Init();
	}

	public XPathLexicalState State = XPathLexicalState.DEFAULT_STATE;

	/**
     * @gwt.typeArgs <java.lang.String, java.lang.Integer>
     */		
	public HashMap Tokens = new HashMap();

	/**
     * @gwt.typeArgs <com.artbase.xpath.client.XPathLexemePattern>
     */	
	public Vector LexemePatterns = new Vector();

	/**
     * @gwt.typeArgs <java.lang.Integer>
     */			
	public Vector Pass1Expr = new Vector();		//tokenize into basic lexemes
	
	/**
     * @gwt.typeArgs <com.artbase.xpath.client.PatternItem>
     */	
	public Vector Pass2Expr = new Vector();		//normalise white space

	/**
     * @gwt.typeArgs <java.lang.Integer>
     */			
	public Vector Pass2ExprUsed = new Vector();		//tokenize into basic lexemes	
	
	/**
     * @gwt.typeArgs <com.artbase.xpath.client.XPathTokenEntry>
     */	
	public Vector Pass3Expr = new Vector(); //tokens with state

	/**
     * @gwt.typeArgs <com.artbase.xpath.client.XPathTokenEntry>
     */		
	public Iterator ItToken = (Iterator) (new Vector()).iterator();  //GWT Compile
	
	//Vector<XPathTokenEntry> ExprStack; //TODO:

	public ExprTreeNode ExprTree = new ExprTreeNode();

	//Dictionary maps to store tokens relating to various lexical states.
	/**
     * @gwt.typeArgs <java.lang.String, com.artbase.xpath.client.ExprToken>
     */		
	public HashMap DictDefault = new HashMap();
	public HashMap DictOperator = new HashMap();
	public HashMap DictQName = new HashMap();
	public HashMap DictItemType = new HashMap();
	public HashMap DictVarName = new HashMap();
	
	private int _tokenParseCount;
	private XPathTokenEntry CurrentToken;
	private int _pass1Count;
	private boolean IsInError = false;
	private String ErrorMsg = "";

	public void Init(){
		/**
	     * @gwt.typeArgs <java.lang.Integer>
	     */			
		this.Pass1Expr = new Vector();
		/**
	     * @gwt.typeArgs <com.artbase.xpath.client.PatternItem>
	     */	
		this.Pass2Expr = new Vector();
		/**
	     * @gwt.typeArgs <com.artbase.xpath.client.XPathTokenEntry>
	     */	
		this.Pass3Expr = new Vector();
		
		/**
	     * @gwt.typeArgs <java.lang.Integer>
	     */	
		this.Pass2ExprUsed = new Vector();
		
		this.ExprTree =  new ExprTreeNode();	
		this.IsInError = false;
		this.ErrorMsg = "";
		InitDictionaries();
	};

	public void InitTokens(){
		//reserve 0 for NCNames
		this.Tokens.put(" ",1);
		this.Tokens.put("\t",2);
		this.Tokens.put("\n",3);
		this.Tokens.put(".",4);
		this.Tokens.put(",",5);
		this.Tokens.put(":",6);
		this.Tokens.put("(",7);
		this.Tokens.put(")",8);
		this.Tokens.put("{",9);
		this.Tokens.put("}",10);
		this.Tokens.put("[",11);
		this.Tokens.put("]",12);
		this.Tokens.put("/",13);
		this.Tokens.put("@",14);
		this.Tokens.put("-",15);
		this.Tokens.put("+",16);
		this.Tokens.put("*",17);
		this.Tokens.put("=",18);
		this.Tokens.put("<",19);
		this.Tokens.put(">",20);
		this.Tokens.put("?",21);
		this.Tokens.put("$",22);

		this.Tokens.put("child",23);
		this.Tokens.put("descendant",24);
		this.Tokens.put("parent",25);
		this.Tokens.put("attribute",26);
		this.Tokens.put("self",27);
		this.Tokens.put("ancestor",28);
		this.Tokens.put("ancestor-or-self",29);
		this.Tokens.put("preceding",30);
		this.Tokens.put("preceding-sibling",31);
		this.Tokens.put("descendant-or-self",32);
		this.Tokens.put("following",33);
		this.Tokens.put("following-sibling",34);
		this.Tokens.put("namespace",35);
		
		this.Tokens.put("text",36);
		this.Tokens.put("comment",37);
		this.Tokens.put("node",38);
		this.Tokens.put("processing-instruction",39);
		
		this.Tokens.put(";",40);

		//Reserved Function Names
		//this.Tokens.put("if",41);
		//this.Tokens.put("typeswitch",42);
		//this.Tokens.put("item",43);
		//this.Tokens.put("element",44);
		//this.Tokens.put("key",45);// was...this.Tokens.put("id",45);
		//this.Tokens.put("key",46);
	};
	
	public void InitLexemePatterns(){
		ExprToken token;

		// "StringLiteral"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(-1);
		token = (ExprToken) this.DictDefault.get("StringLiteral");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("StringLiteral", token));
		token = (ExprToken) this.DictOperator.get("StringLiteral");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("StringLiteral", token));		
		
		// "IntegerLiteral"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(-2);
		token = (ExprToken) this.DictDefault.get("IntegerLiteral");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("IntegerLiteral", token));
		token = (ExprToken) this.DictOperator.get("IntegerLiteral");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("IntegerLiteral", token));	
		
		// "DecimalLiteral"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(-3);
		token = (ExprToken) this.DictDefault.get("DecimalLiteral");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("DecimalLiteral", token));
		token = (ExprToken) this.DictOperator.get("DecimalLiteral");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("DecimalLiteral", token));

		// "DoubleLiteral"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(-4);
		token = (ExprToken) this.DictDefault.get("DoubleLiteral");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("DoubleLiteral", token));
		token = (ExprToken) this.DictOperator.get("DoubleLiteral");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("DoubleLiteral", token));

		// "/"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(13);
		token = (ExprToken) this.DictDefault.get("/");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("/", token));
		token = (ExprToken) this.DictQName.get("/");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("/", token));
		token = (ExprToken) this.DictOperator.get("/");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("/", token));

		// "//"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(13);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(13);
		token = (ExprToken) this.DictDefault.get("//");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("//", token));
		token = (ExprToken) this.DictQName.get("//");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("//", token));
		token = (ExprToken) this.DictOperator.get("//");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("//", token));

		// "@"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(14);
		token = (ExprToken) this.DictDefault.get("attribute::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("attribute::", token));
		token = (ExprToken) this.DictQName.get("attribute::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("attribute::", token));

		// "["
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(11);
		token = (ExprToken) this.DictDefault.get("[");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("[", token));
		token = (ExprToken) this.DictOperator.get("[");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("[", token));

		// "]"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(12);
		token = (ExprToken) this.DictDefault.get("]");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("]", token));
		token = (ExprToken) this.DictOperator.get("]");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("]", token));

		// "NCName" = QName LocalPart
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(0);
		token = (ExprToken) this.DictQName.get("LocalPart");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("LocalPart", token));
		token = (ExprToken) this.DictDefault.get("LocalPart");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("LocalPart", token));
		token = (ExprToken) this.DictVarName.get("LocalPart");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("LocalPart", token));

		// "NCName:NCName" = QName
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(0);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(0);
		token = (ExprToken) this.DictDefault.get("NCName:NCName");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("NCName:NCName", token));
		token = (ExprToken) this.DictQName.get("NCName:NCName");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("NCName:NCName", token));
		token = (ExprToken) this.DictVarName.get("NCName:NCName");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("NCName:NCName", token));

		// "*:NCName" = Wildcard Namespace Prefix QName
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(17);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(0);
		token = (ExprToken) this.DictDefault.get("*:NCName");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("*:NCName", token));
		token = (ExprToken) this.DictQName.get("*:NCName");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("*:NCName", token));

		// "NCName:*" = Wildcard Local Name for given namespace prefix
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(0);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(17);
		token = (ExprToken) this.DictQName.get("NCName:*");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("NCName:*", token));

		// "*" = QName wildcard ...everything
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(17);
		token = (ExprToken) this.DictDefault.get("*");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("*", token));
		token = (ExprToken) this.DictQName.get("*");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("*", token));
		// ....as multiplication operator
		token = (ExprToken) this.DictOperator.get("*");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("*", token));

		// "child::"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(23);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		token = (ExprToken) this.DictDefault.get("child::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("child::", token));
		token = (ExprToken) this.DictQName.get("child::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("child::", token));

		// "self::"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(27);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		token = (ExprToken) this.DictDefault.get("self::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("self::", token));
		token = (ExprToken) this.DictQName.get("self::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("self::", token));

		// "descendant::"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(24);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		token = (ExprToken) this.DictDefault.get("descendant::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("descendant::", token));
		token = (ExprToken) this.DictQName.get("descendant::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("descendant::", token));

		// "parent::"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(25);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		token = (ExprToken) this.DictDefault.get("parent::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("parent::", token));
		token = (ExprToken) this.DictQName.get("parent::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("parent::", token));

		// "attribute::"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(26);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		token = (ExprToken) this.DictDefault.get("attribute::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("attribute::", token));
		token = (ExprToken) this.DictQName.get("attribute::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("attribute::", token));

		// "ancestor::"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(28);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		token = (ExprToken) this.DictDefault.get("ancestor::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("ancestor::", token));
		token = (ExprToken) this.DictQName.get("ancestor::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("ancestor::", token));

		// "ancestor-or-self::"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(29);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		token = (ExprToken) this.DictDefault.get("ancestor-or-self::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("ancestor-or-self::", token));
		token = (ExprToken) this.DictQName.get("ancestor-or-self::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("ancestor-or-self::", token));

		// "preceding::"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(30);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		token = (ExprToken) this.DictDefault.get("preceding::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("preceding::", token));
		token = (ExprToken) this.DictQName.get("preceding::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("preceding::", token));

		// "preceding-sibling::"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(31);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		token = (ExprToken) this.DictDefault.get("preceding-sibling::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("preceding-sibling::", token));
		token = (ExprToken) this.DictQName.get("preceding-sibling::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("preceding-sibling::", token));

		// "descendant-or-self::"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(32);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		token = (ExprToken) this.DictDefault.get("descendant-or-self::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("descendant-or-self::", token));
		token = (ExprToken) this.DictQName.get("descendant-or-self::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("descendant-or-self::", token));

		// "following::"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(33);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		token = (ExprToken) this.DictDefault.get("following::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("following::", token));
		token = (ExprToken) this.DictQName.get("following::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("following::", token));

		// "following-sibling::"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(34);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		token = (ExprToken) this.DictDefault.get("following-sibling::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("following-sibling::", token));
		token = (ExprToken) this.DictQName.get("following-sibling::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("following-sibling::", token));

		// "namespace::"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(35);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		token = (ExprToken) this.DictDefault.get("namespace::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("namespace::", token));
		token = (ExprToken) this.DictQName.get("namespace::");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("namespace::", token));

		// text()
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(36);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(7);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(8);
		token = (ExprToken) this.DictDefault.get("text()");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("text()", token));
		token = (ExprToken) this.DictQName.get("text()");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("text()", token));

		// comment()
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(37);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(7);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(8);
		token = (ExprToken) this.DictDefault.get("comment()");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("comment()", token));
		token = (ExprToken) this.DictQName.get("comment()");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("comment()", token));

		// node()
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(38);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(7);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(8);
		token = (ExprToken) this.DictDefault.get("node()");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("node()", token));
		token = (ExprToken) this.DictQName.get("node()");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("node()", token));

		// processing-instruction()
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(39);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(7);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(8);
		token = (ExprToken) this.DictDefault.get("processing-instruction()");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("processing-instruction()", token));
		token = (ExprToken) this.DictQName.get("processing-instruction()");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("processing-instruction()", token));

		// variable prefix
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(22);
		token = (ExprToken) this.DictDefault.get("$");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("$", token));
		token = (ExprToken) this.DictQName.get("$");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("$", token));
		token = (ExprToken) this.DictOperator.get("$");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("$", token));
		//TODO:
		//token = this.DictItemType.get("$");
		//((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("", token));

		//functions
		// "NCName(" = QName LocalPart (
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(0);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(7);
		token = (ExprToken) this.DictDefault.get("LocalPart(");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("LocalPart(", token));
		
		// "NCName:NCName(" = QName
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(0);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(6);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(0);
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(7);
		token = (ExprToken) this.DictDefault.get("NCName:NCName(");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("NCName:NCName(", token));

		// ","
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(5);
		token = (ExprToken) this.DictDefault.get(",");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair(",", token));
		token = (ExprToken) this.DictQName.get(",");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair(",", token));
		token = (ExprToken) this.DictOperator.get(",");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair(",", token));

		// "("
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(7);
		token = (ExprToken) this.DictDefault.get("(");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("(", token));
		token = (ExprToken) this.DictQName.get("(");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("(", token));
		token = (ExprToken) this.DictOperator.get("(");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair("(", token));

		// ")"
		this.LexemePatterns.add(new XPathLexemePattern());
		((XPathLexemePattern)this.LexemePatterns.lastElement()).Pattern.add(8);
		token = (ExprToken) this.DictDefault.get(")");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair(")", token));
		token = (ExprToken) this.DictQName.get(")");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair(")", token));
		token = (ExprToken) this.DictOperator.get(")");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair(")", token));
		token = (ExprToken) this.DictItemType.get(")");
		((XPathLexemePattern)this.LexemePatterns.lastElement()).TokenMap.add(new PatternTokenPair(")", token));		
		
	};
	
	public void InitDictionaries(){
		InitDefaultDictionary();
		InitOperatorDictionary();
		InitQNameDictionary();
		InitItemTypeDictionary();
		InitVarNameDictionary();
		InitTokens();
		InitLexemePatterns();		
	};

	public void InitDefaultDictionary(){
		this.DictDefault.put("(",new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.LEFTPAREN,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.DEFAULT_STATE,0));
		this.DictDefault.put(")", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.RIGHTPAREN,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.OPERATOR_STATE,0));

		// "StringLiteral" 
		this.DictDefault.put("StringLiteral", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.STRING_LITERAL,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictDefault.put("IntegerLiteral", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.INTEGER_LITERAL,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictDefault.put("DecimalLiteral", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.DECIMAL_LITERAL,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictDefault.put("DoubleLiteral", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.DOUBLE_LITERAL,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.OPERATOR_STATE,0));

		//steps
		this.DictDefault.put("/", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.FORWARDSLASH,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.QNAME_STATE,0));
		this.DictDefault.put("//", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.DOUBLE_FORWARDSLASH,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.QNAME_STATE,0));

		// axis
		this.DictDefault.put("child::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.CHILD_AXIS,XPathLexicalState.DEFAULT_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictDefault.put("descendant::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.DESCENDANT_AXIS,XPathLexicalState.DEFAULT_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictDefault.put("parent::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.PARENT_AXIS,XPathLexicalState.DEFAULT_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictDefault.put("attribute::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.ATTRIBUTE_AXIS,XPathLexicalState.DEFAULT_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictDefault.put("self::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.SELF_AXIS,XPathLexicalState.DEFAULT_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictDefault.put("descendant-or-self::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.DESCENDANT_OR_SELF_AXIS,XPathLexicalState.DEFAULT_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictDefault.put("ancestor::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.ANCESTOR_AXIS,XPathLexicalState.DEFAULT_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictDefault.put("ancestor-or-self::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.ANCESTOR_OR_SELF_AXIS,XPathLexicalState.DEFAULT_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictDefault.put("following-sibling::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.FOLLOWING_SIBLING_AXIS,XPathLexicalState.DEFAULT_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictDefault.put("following::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.FOLLOWING_AXIS,XPathLexicalState.DEFAULT_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictDefault.put("preceding::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.PRECEDING_AXIS,XPathLexicalState.DEFAULT_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictDefault.put("preceding-sibling::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.PRECEDING_SIBLING_AXIS,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.QNAME_STATE,6));
		this.DictDefault.put("namespace::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.NAMESPACE_AXIS,XPathLexicalState.DEFAULT_STATE, XPathLexicalState.QNAME_STATE,6));

		//names
		this.DictDefault.put("*", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.WILDCARD,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictDefault.put("NCName:*",	new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.LOCALNAME_WILDCARD,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictDefault.put("*:NCName",	new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.NAMESPACE_WILDCARD,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictDefault.put("LocalPart",	new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.LOCALNAME,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictDefault.put("NCName:NCName", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.QNAME,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.OPERATOR_STATE,0));

		this.DictDefault.put("LocalPart(",	new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.LOCALNAME_CALL,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.DEFAULT_STATE,6));
		this.DictDefault.put("NCName:NCName(", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.QNAME_CALL,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.DEFAULT_STATE,6));

		//node tests
		this.DictDefault.put("text()", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.TEXT_NODE_TEST,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.DEFAULT_STATE,0));
		this.DictDefault.put("comment()",	new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.COMMENT_NODE_TEST,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.DEFAULT_STATE,0));
		this.DictDefault.put("node()",	new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.ANY_NODE_TEST,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.DEFAULT_STATE,0));
		this.DictDefault.put("processing-instruction()",	new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.PI_NODE_TEST,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.DEFAULT_STATE,0));

		//variable prefix
		this.DictDefault.put("$", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.VARIABLE_MARKER,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.VARNAME_STATE,0));

		//"," comma delimiter
		this.DictDefault.put(",", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.COMMA,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.DEFAULT_STATE,0));

		//"[" "]" predicates
		this.DictDefault.put("[", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.OPEN_BRACKET,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.DEFAULT_STATE,0));
		this.DictDefault.put("]", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.CLOSE_BRACKET,XPathLexicalState.DEFAULT_STATE,XPathLexicalState.OPERATOR_STATE,0));
	};
	
	public void InitOperatorDictionary(){
		
		this.DictOperator.put("(", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.LEFTPAREN,XPathLexicalState.OPERATOR_STATE,XPathLexicalState.DEFAULT_STATE,0));
		this.DictOperator.put(")", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.RIGHTPAREN,XPathLexicalState.OPERATOR_STATE,XPathLexicalState.OPERATOR_STATE,0));

		this.DictOperator.put("/", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.FORWARDSLASH,XPathLexicalState.OPERATOR_STATE,XPathLexicalState.DEFAULT_STATE,6));
		this.DictOperator.put("//", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.DOUBLE_FORWARDSLASH,XPathLexicalState.OPERATOR_STATE,XPathLexicalState.DEFAULT_STATE,6));

		// "StringLiteral" 
		this.DictOperator.put("StringLiteral", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.STRING_LITERAL,XPathLexicalState.OPERATOR_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictOperator.put("IntegerLiteral", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.INTEGER_LITERAL,XPathLexicalState.OPERATOR_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictOperator.put("DecimalLiteral", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.DECIMAL_LITERAL,XPathLexicalState.OPERATOR_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictOperator.put("DoubleLiteral", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.DOUBLE_LITERAL,XPathLexicalState.OPERATOR_STATE,XPathLexicalState.OPERATOR_STATE,0));

		this.DictOperator.put("$", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.VARIABLE_MARKER,XPathLexicalState.OPERATOR_STATE,XPathLexicalState.VARNAME_STATE,0));

		this.DictOperator.put("*", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.MULTIPLY,XPathLexicalState.OPERATOR_STATE, XPathLexicalState.DEFAULT_STATE,5));

		//"," comma delimiter
		this.DictOperator.put(",", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.COMMA,XPathLexicalState.OPERATOR_STATE,XPathLexicalState.DEFAULT_STATE,0));

		//"[" "]" predicates
		this.DictOperator.put("[", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.OPEN_BRACKET,XPathLexicalState.OPERATOR_STATE,XPathLexicalState.DEFAULT_STATE,0));
		this.DictOperator.put("]", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.CLOSE_BRACKET,XPathLexicalState.OPERATOR_STATE,XPathLexicalState.OPERATOR_STATE,0));

		//"=" equals
		this.DictOperator.put("=",new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.EQUALS,XPathLexicalState.OPERATOR_STATE,XPathLexicalState.DEFAULT_STATE,0));		
		
	};
	
	public void InitQNameDictionary(){
		this.DictQName.put("(",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.LEFTPAREN,XPathLexicalState.QNAME_STATE,XPathLexicalState.DEFAULT_STATE,0));
		this.DictQName.put(")",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.RIGHTPAREN,XPathLexicalState.QNAME_STATE,XPathLexicalState.OPERATOR_STATE,0));

		//name tests
		this.DictQName.put("*", 	new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.WILDCARD,XPathLexicalState.QNAME_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictQName.put("NCName:*",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.LOCALNAME_WILDCARD,XPathLexicalState.QNAME_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictQName.put("*:NCName",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.NAMESPACE_WILDCARD,XPathLexicalState.QNAME_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictQName.put("LocalPart",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.LOCALNAME,XPathLexicalState.QNAME_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictQName.put("NCName:NCName",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.QNAME,XPathLexicalState.QNAME_STATE,XPathLexicalState.OPERATOR_STATE,0));

		//steps
		this.DictQName.put("/",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.FORWARDSLASH,XPathLexicalState.QNAME_STATE,XPathLexicalState.QNAME_STATE,6));
		this.DictQName.put("//",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.DOUBLE_FORWARDSLASH,XPathLexicalState.QNAME_STATE,XPathLexicalState.QNAME_STATE,6));

		//axis
		this.DictQName.put("child::",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.CHILD_AXIS,XPathLexicalState.QNAME_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictQName.put("descendant::",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.DESCENDANT_AXIS,XPathLexicalState.QNAME_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictQName.put("parent::",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.PARENT_AXIS,XPathLexicalState.QNAME_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictQName.put("attribute::",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.ATTRIBUTE_AXIS,XPathLexicalState.QNAME_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictQName.put("self::",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.SELF_AXIS,XPathLexicalState.QNAME_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictQName.put("descendant-or-self::",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.DESCENDANT_OR_SELF_AXIS,XPathLexicalState.QNAME_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictQName.put("ancestor::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.ANCESTOR_AXIS,XPathLexicalState.QNAME_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictQName.put("ancestor-or-self::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.ANCESTOR_OR_SELF_AXIS,XPathLexicalState.QNAME_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictQName.put("following-sibling::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.FOLLOWING_SIBLING_AXIS,XPathLexicalState.QNAME_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictQName.put("following::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.FOLLOWING_AXIS,XPathLexicalState.QNAME_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictQName.put("preceding::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.PRECEDING_AXIS,XPathLexicalState.QNAME_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictQName.put("preceding-sibling::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.PRECEDING_SIBLING_AXIS,XPathLexicalState.QNAME_STATE, XPathLexicalState.QNAME_STATE,6));
		this.DictQName.put("namespace::", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.NAMESPACE_AXIS,XPathLexicalState.QNAME_STATE, XPathLexicalState.QNAME_STATE,6));

		//node tests
		this.DictQName.put("text()",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.TEXT_NODE_TEST,XPathLexicalState.QNAME_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictQName.put("comment()",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.COMMENT_NODE_TEST,XPathLexicalState.QNAME_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictQName.put("node()",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.ANY_NODE_TEST,XPathLexicalState.QNAME_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictQName.put("processing-instruction()",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.PI_NODE_TEST,XPathLexicalState.QNAME_STATE,XPathLexicalState.OPERATOR_STATE,0));

		//var prefix
		this.DictQName.put("$",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.VARIABLE_MARKER,XPathLexicalState.QNAME_STATE,XPathLexicalState.VARNAME_STATE,0));

		//"," comma delimiter
		this.DictQName.put(",",  new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.COMMA,XPathLexicalState.QNAME_STATE,XPathLexicalState.DEFAULT_STATE,0));
	};
	
	public void InitItemTypeDictionary(){
		this.DictItemType.put(")", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.RIGHTPAREN,XPathLexicalState.ITEMTYPE_STATE,XPathLexicalState.OPERATOR_STATE,0));		
	};
	
	public void InitVarNameDictionary(){
		//rather than create a varname token have included the two acceptable forms of QName
		this.DictVarName.put("LocalPart", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.LOCALNAME,XPathLexicalState.VARNAME_STATE,XPathLexicalState.OPERATOR_STATE,0));
		this.DictVarName.put("NCName:NCName", new ExprToken(XPathTokenType.XXXTEMPXXX,XPathTokenName.QNAME,XPathLexicalState.VARNAME_STATE,XPathLexicalState.OPERATOR_STATE,0));		
	};

	public void ParseExpression(String sExpr){
		//first pass, convert expression string to an
		//array of basic lexemes. Minimal error checking.
		//SCAN
		this.BuildBasicLexeme(sExpr);
		this.NormaliseWhiteSpace(); //second pass ...at the moment this actually deletes ws
		this.Tokenize(); //third pass
		if(this.Pass2Expr.size()!=this.Pass2ExprUsed.size()){
			this.IsInError = true;
			this.ErrorMsg = "";
			for(int i = 0; i < this.Pass2Expr.size();i++){
				boolean found = false;
				for(int j = 0; j < this.Pass2ExprUsed.size(); j++){
					if(((PatternItem)this.Pass2Expr.get(i)).OriginalPosition == ((PatternItem)this.Pass2ExprUsed.get(j)).OriginalPosition){
						found = true;
						break;
					}
				}
				if(found){
					this.ErrorMsg += getTokenName(i);
				}
				else this.ErrorMsg += "<span style='color:red'>"+getTokenName(i)+"</span>";
			}
		}
		if(!this.IsInError){
			//PARSE
			this.BuildExprTree();
		}
	}

	private String getTokenName(int i) {
		String result = "";
		Iterator it = this.Tokens.keySet().iterator();
		while(it.hasNext()){
			String key = (String) it.next(); 
			if((Integer)this.Tokens.get(key)==((PatternItem)this.Pass2Expr.get(i)).Value){
				return key;						
			}
		}
		return result;
	};

	public void BuildBasicLexeme(String sExpr){

		char ch; 
		for(_pass1Count=0; _pass1Count<(int)sExpr.length();_pass1Count++){
			ch = sExpr.charAt(_pass1Count);
			Integer tokenid = (Integer) this.Tokens.get(ch+"");
			if(tokenid!=null && tokenid <= XPATH_NUM_KNOWN_BASIC_TOKENS){ //this is a known symbol
				this.Pass1Expr.add(tokenid);
			}
			else {
				String wordToken = "";
				if(Character.isDigit(ch))
					wordToken = GetNumber(sExpr);
				else if(ch=='\"')
					wordToken = GetStringLiteral(sExpr,'"');
				else if(ch=='\'')
					wordToken = GetStringLiteral(sExpr,'\'');
				else
					wordToken = GetWord(sExpr);
				if(wordToken!=""){
					tokenid = (Integer) this.Tokens.get(wordToken);
					if(tokenid!=null){
						this.Pass1Expr.add(tokenid); //add to expr list
					}
					else { //create new token
						int newid = this.Tokens.size()+1;
						this.Tokens.put(wordToken,newid); 
						this.Pass1Expr.add(newid);
					}
				}
			}
		}		
	}
	
	public void NormaliseWhiteSpace(){
		/**
	     * @gwt.typeArgs <java.lang.Integer>
	     */	
		Iterator it = this.Pass1Expr.iterator();
		int current = (Integer) it.next();
		//discard leading ws
		if(IsWhitespace(current)){
			while((IsWhitespace(current)) && it.hasNext()){
				current = (Integer) it.next();
			}
		}
		this.Pass2Expr.add(new PatternItem(current,0));
		int pos = 0;
		//collapse contained ws 
		//int countws = 0;
		while(it.hasNext()){
			current = (Integer) it.next();			
			if(IsWhitespace(current)) {
				; //do nothing
			}
			else {
				this.Pass2Expr.add(new PatternItem(current,++pos));
			}
		}

	}

	public void Tokenize(){
		this.State = XPathLexicalState.DEFAULT_STATE;
		/**
	     * @gwt.typeArgs <com.artbase.xpath.client.XPathTokenEntry>
	     */	
		Vector te = new Vector();
		for(_tokenParseCount=0;_tokenParseCount<(int)this.Pass2Expr.size();_tokenParseCount++){
			te.clear();
			te = GetPatternMatch();
			if(te != null){ 
				this.Pass3Expr.addAll(te);
			}
		}
	};
	
	public void BuildExprTree(){
		this.ItToken = (Iterator) this.Pass3Expr.iterator();
		if(this.ItToken.hasNext()){
			this.CurrentToken = (XPathTokenEntry) this.ItToken.next();
			this.ExprTree = XPath();
			this.ExprTree.IsRoot = true;
		}
	}

	public XPathTokenEntry GetChildAxisTokenEntry(){
		return new XPathTokenEntry(new PatternTokenPair("child::",(ExprToken) DictQName.get("child::")));
	}
	
	public XPathTokenEntry GetFunctionCallTokenEntry(XPathTokenName name){
		ExprToken token = null;
		String sname = "";
		switch(name){
			case QNAME_CALL:
				sname = "NCName:NCName(";
				token = (ExprToken) this.DictDefault.get(sname);
				break;
			case LOCALNAME_CALL:
				sname = "LocalPart(";				
				token = (ExprToken) this.DictDefault.get("LocalPart(");
				break;
		}
		if(token!=null){
			return new XPathTokenEntry(new PatternTokenPair(sname,token));
		}
		
		return null;		
		
	};
	
	//	Vector<XPathTokenEntry> GetInitialStepTokenEntries(int kind); //TODO:
	//	Vector<XPathTokenEntry> GetDOSTokenEntries(); //TODO:

	/**
     * @gwt.typeArgs <com.artbase.xpath.client.XPathTokenEntry>
     */		
	public Vector GetPatternMatch(){
		//TODO: a test to see if all elements in the expression pass have been tokenized.
		/**
	     * @gwt.typeArgs <com.artbase.xpath.client.XPathTokenEntry>
	     */	
		Vector result = new Vector(); //GWT Compile
		int startCount = _tokenParseCount;
		int lookahead = ((_tokenParseCount+XPATH_MAX_PATTERN_LOOKAHEAD)>=this.Pass2Expr.size())?
						this.Pass2Expr.size()-(_tokenParseCount+1):
						XPATH_MAX_PATTERN_LOOKAHEAD;
		int jumpahead = 0;
		
		/**
	     * @gwt.typeArgs <com.artbase.xpath.client.PatternItem>
	     */			
		Vector originalPattern = new Vector();
		/**
	     * @gwt.typeArgs <com.artbase.xpath.client.PatternItem>
	     */			
		Vector patternBuffer = new Vector();

		
		PatternItem t = null; 
		boolean match = false;
		for(int i = 0; i<=lookahead; i++){
			t = (PatternItem) this.Pass2Expr.get(_tokenParseCount+i);
			originalPattern.add(t);
			if(t.Value>XPATH_NUM_KNOWN_BASIC_TOKENS) {
				t = new PatternItem(this.ClassifyUnknownLexeme(t.Value),t.Value);
			}
			patternBuffer.add(t);
		}

		/**
	     * @gwt.typeArgs <com.artbase.xpath.client.XPathLexemePattern>
	     */	
		Iterator it = (Iterator) this.LexemePatterns.iterator(); 
		do {
			it = (Iterator) this.LexemePatterns.iterator(); 			
			while(it.hasNext()){
				XPathLexemePattern i = (XPathLexemePattern) it.next();
				if(isPatternBufferAPattern(patternBuffer,i.Pattern)){
					match = true;
					jumpahead = lookahead;
					break;
				}
			}		
			if(!match) {
				if(patternBuffer.size()>0){
					patternBuffer.remove(patternBuffer.size()-1);
				}
				lookahead--;
			}
		} while (!match && lookahead>=0);

		if(match) {
			it = (Iterator) this.LexemePatterns.iterator();
			boolean foundToken = false;
			while(it.hasNext() && !foundToken)	{
				XPathLexemePattern current = (XPathLexemePattern) it.next();
				if(isPatternBufferAPattern(patternBuffer,current.Pattern)){
					foundToken = false; //must not add two tokens for the same pattern
										//this is important in the case where a token sets
										//the state to a value equal to another token
										//in the token list for the pattern.
					this.Pass2ExprUsed.addAll(patternBuffer); //account for used symbols
					for(int i=0;i<current.TokenMap.size();i++){
						if(this.State==((PatternTokenPair)current.TokenMap.get(i)).Token.State && !foundToken){
							foundToken = true;
							this.State = ((PatternTokenPair)current.TokenMap.get(i)).Token.ToState;
							result.add(new XPathTokenEntry(new PatternTokenPair(((PatternTokenPair)current.TokenMap.get(i)).Pattern,((PatternTokenPair)current.TokenMap.get(i)).Token)));
							String tokenName = ((PatternTokenPair)current.TokenMap.get(i)).Pattern;
							String name = "";
							String precedingToken = ((this.Pass3Expr.size() > 0)?((XPathTokenEntry)this.Pass3Expr.lastElement()).Token.Pattern:"");
							if(tokenName=="LocalPart"){
								if( (precedingToken=="/") || 
									(precedingToken=="//") ||
									(precedingToken=="[") ||
									(precedingToken=="") ||
									(((PatternTokenPair)current.TokenMap.get(i)).Token.State==XPathLexicalState.DEFAULT_STATE) ){
									//It's ok to insert token here because it will not effect state.
									result.add(0,GetChildAxisTokenEntry());
								}
								((XPathTokenEntry)result.lastElement()).Info.add(new XPathTokenInfo());
								name = GetLexemeTokenString(((PatternItem)originalPattern.get(0)).Value);
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Value = name;
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Type = "string";
							}
							else if(tokenName=="StringLiteral"){ 
								((XPathTokenEntry)result.lastElement()).Info.add(new XPathTokenInfo());
								name = GetLexemeTokenString(((PatternItem)originalPattern.get(0)).Value);
								//TODO: name->erase(name->begin());
								//TODO: name->erase(name->end()-1);
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Value = name;
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Type = "string";
							}
							else if(tokenName=="IntegerLiteral"){
								if(precedingToken=="["){
									//abreviation somenode[5] => somenode[position()=5]
									ExprToken jt;
									jt = (ExprToken) this.DictOperator.get("=");
									if(jt!=null){
										result.add(0,new XPathTokenEntry(new PatternTokenPair("=",jt)));
									}
									jt = (ExprToken) this.DictDefault.get(")");
									if(jt!=null){
										result.add(0,new XPathTokenEntry(new PatternTokenPair(")",jt)));
									}
									XPathTokenEntry te = GetFunctionCallTokenEntry(XPathTokenName.QNAME_CALL);
									te.Info.add(new XPathTokenInfo());
									name = "fn";
									((XPathTokenInfo)te.Info.lastElement()).Value = name;
									((XPathTokenInfo)te.Info.lastElement()).Type = "string";
									te.Info.add(new XPathTokenInfo());
									name = "position";
									((XPathTokenInfo)te.Info.lastElement()).Value = name;
									((XPathTokenInfo)te.Info.lastElement()).Type = "string";
									result.add(0,te);
								}
								((XPathTokenEntry)result.lastElement()).Info.add(new XPathTokenInfo());
								name = GetLexemeTokenString(((PatternItem)originalPattern.get(0)).Value);
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Value = Integer.parseInt(name);
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Type = "integer";
							}
							else if(tokenName=="DoubleLiteral"){ 
								((XPathTokenEntry)result.lastElement()).Info.add(new XPathTokenInfo());
								name = GetLexemeTokenString(((PatternItem)originalPattern.get(0)).Value);
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Value = Double.parseDouble(name);
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Type = "double";
							}
							else if(tokenName=="NCName:NCName"){
								if( (precedingToken=="/") || 
									(precedingToken=="//") ||
									(precedingToken=="[") ||
									(precedingToken=="") ){
									result.add(0,GetChildAxisTokenEntry());
								}
								((XPathTokenEntry)result.lastElement()).Info.add(new XPathTokenInfo());
								name = GetLexemeTokenString(((PatternItem)originalPattern.get(0)).Value);
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Value = name;
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Type = "string";
								((XPathTokenEntry)result.lastElement()).Info.add(new XPathTokenInfo());
								name = GetLexemeTokenString(((PatternItem)originalPattern.get(2)).Value);
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Value = name;
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Type = "string";
							}
							else if(tokenName=="*"){
								if( (precedingToken=="/") || 
									(precedingToken=="//") ||
									(precedingToken=="[") ||
									(precedingToken=="") ){
									result.add(0,GetChildAxisTokenEntry());
								}
								((XPathTokenEntry)result.lastElement()).Info.add(new XPathTokenInfo());
							}
							else if(tokenName=="NCName:*"){
								if( (precedingToken=="/") || 
									(precedingToken=="//") ||
									(precedingToken=="[")||
									(precedingToken=="")){
									result.add(0,GetChildAxisTokenEntry());
								}
								((XPathTokenEntry)result.lastElement()).Info.add(new XPathTokenInfo());
								name = GetLexemeTokenString(((PatternItem)originalPattern.get(0)).Value);
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Value = name;
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Type = "string";
							}
							else if(tokenName=="*:NCName"){
								if( (precedingToken=="/") || 
									(precedingToken=="//") ||
									(precedingToken=="[")  ||
									(precedingToken=="") ){
									result.add(0,GetChildAxisTokenEntry());
								}
								((XPathTokenEntry)result.lastElement()).Info.add(new XPathTokenInfo());
								name = GetLexemeTokenString(((PatternItem)originalPattern.get(2)).Value);
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Value = name;
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Type = "string";
							}
							else if(tokenName=="NCName:NCName("){
								((XPathTokenEntry)result.lastElement()).Info.add(new XPathTokenInfo());
								name = GetLexemeTokenString(((PatternItem)originalPattern.get(0)).Value);
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Value = name;
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Type = "string";
								((XPathTokenEntry)result.lastElement()).Info.add(new XPathTokenInfo());
								name = GetLexemeTokenString(((PatternItem)originalPattern.get(2)).Value);
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Value = name;
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Type = "string";
							}
							else if(tokenName=="LocalPart("){
								((XPathTokenEntry)result.lastElement()).Info.add(new XPathTokenInfo());
								name = GetLexemeTokenString(((PatternItem)originalPattern.get(0)).Value);
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Value = name;
								((XPathTokenInfo)((XPathTokenEntry)result.lastElement()).Info.lastElement()).Type = "string";
							}
							else if(tokenName=="node()" || 
									tokenName=="text()" || 
									tokenName=="comment()" || 
									tokenName=="processing-instruction()"){
								if( (precedingToken=="/") || 
									(precedingToken=="//") ||
									(precedingToken=="[") ||
									(precedingToken=="") ||
									(((PatternTokenPair)current.TokenMap.get(i)).Token.State==XPathLexicalState.DEFAULT_STATE) ){
									//It's ok to insert token here because it will
									//not effect state.
									result.add(0,GetChildAxisTokenEntry());
								}
							}
						}
					}
				}
			}
		}
		_tokenParseCount = startCount + jumpahead;
		return result;
	};
	
	public String GetWord(String s){ //TODO: better support XML
		boolean endofword = false;
		String result = "";
		result += s.charAt(_pass1Count);
		while(_pass1Count<s.length() && !endofword){
			if(_pass1Count!=s.length()-1){
				if(IsKnownSymbol(s,_pass1Count+1)) {
					if(s.charAt(_pass1Count+1)=='-' || s.charAt(_pass1Count+1)=='.') {
						result += s.charAt(++_pass1Count);
					}
					else endofword=true;
				}
				else result += s.charAt(++_pass1Count);
			}
			else endofword=true;
		}
		return result;
	};
	
	public String GetNumber(String s){
		boolean endofword = false;
		String result = "";
		int countPeriod = 0;
		result += s.charAt(_pass1Count);
		while(_pass1Count<s.length() && !endofword){
			if(_pass1Count!=s.length()-1){
				if(s.charAt(_pass1Count+1)=='.'){
					if(countPeriod==0) {
						result += s.charAt(++_pass1Count);
						countPeriod++;
					}
					else endofword=true; 
				}
				else if(Character.isDigit(s.charAt(_pass1Count+1))){
					result += s.charAt(++_pass1Count);
				}
				else endofword=true;
			}
			else endofword=true;
		}
		return result;
	};
	
	public String GetStringLiteral(String s, char delimit){
		boolean endofword = false;
		String result = "";
		int countQuote = 1;
		while(_pass1Count<(int)s.length() && !endofword){
			if(_pass1Count!=s.length()-1){
				if(s.charAt(_pass1Count+1)!=delimit){
					result += s.charAt(++_pass1Count);
				}
				else if(s.charAt(_pass1Count+2) == delimit){
					result += delimit;
					_pass1Count += 2;
					countQuote += 2;
				}
				else {
					_pass1Count++;
					countQuote++;
					endofword=true; 
				}
			}
			else endofword=true;
		}
		if(countQuote%2!=0) ; //TODO: throw error unclosed quote.
		return delimit + result + delimit;
	};
	
	private boolean IsWhitespace(int current) {
		return current==1 || current==2 || current==3;
	}	
	
	public boolean IsWhiteSpace(char c){
		return ( (c==' ') || (c=='\t') || (c=='\n') );
	};
	
	public boolean IsKnownSymbol(String s, int c){
		String key = s.charAt(c)+"";
		if(this.Tokens.containsKey(key))
			return ((Integer)this.Tokens.get(key))<=XPATH_NUM_KNOWN_BASIC_TOKENS?true:false;
		else 
			return false;
	};

	public int ClassifyUnknownLexeme(int i){
		int result = 1;
		String ts = this.GetLexemeTokenString(i);
		if(Character.isLetter(ts.charAt(0))) result = 0;
		else if(ts.charAt(0)=='"' || ts.charAt(0)=='\'') result = -1;
		else if(Character.isDigit(ts.charAt(0))) result = -2;
		return result;		
	};
	
	public String GetLexemeTokenString(int id){
		String result = null;
		if(this.Tokens.containsValue(id)){
			/**
		     * @gwt.typeArgs <java.lang.String>
		     */				
			Iterator it = this.Tokens.keySet().iterator();
			while(it.hasNext()){
				String i = (String) it.next();
				if(((Integer)this.Tokens.get(i))==id){
					return i;
				}
			}
		}
		return result;		
	};

	/**
     * @gwt.typeArgs <java.lang.String,com.artbase.xpath.client.ExprToken>
     */		
	public HashMap GetDictionaryForState(){
		/**
	     * @gwt.typeArgs <java.lang.String,com.artbase.xpath.client.ExprToken>
	     */		
		HashMap result = new HashMap(); // GWT Compile 
		switch(this.State){
			case DEFAULT_STATE: result = this.DictDefault; break;
		}
		return result;		
	};

	//XPATH EXPRESSION PARSER
	public XPathTokenName GetTokenName(){
		if(CurrentToken!=null)
			return CurrentToken.Token.Token.Name;
		else
			return XPathTokenName.ENDEXPR;	
	};
	
	public boolean MatchToken(XPathTokenName t){
		if(GetTokenName()==t){
			if(ItToken.hasNext()){
				CurrentToken = (XPathTokenEntry) ItToken.next();
			}
			return true;			
		}
		else return false;
	};
	
	public boolean RecogniseNonTerminal(XPathNonTerminal nt){
		XPathTokenName tokenName = GetTokenName();
		boolean result = false;
		switch(nt){
			case PARENTHESIZED_EXPR :
				if( tokenName == XPathTokenName.LEFTPAREN )
					result = true;
				return result;
			case PATH_EXPR :
				if( tokenName == XPathTokenName.FORWARDSLASH ||
					tokenName == XPathTokenName.DOUBLE_FORWARDSLASH ||
					RecogniseNonTerminal(XPathNonTerminal.RELATIVE_PATH_EXPR) ) 
					result = true;
				return result;
			case RELATIVE_PATH_EXPR : 
				if( IsTokenForwardAxis(tokenName)||
					IsTokenReverseAxis(tokenName)||
					IsTokenLiteral(tokenName)||
					tokenName == XPathTokenName.VARIABLE_MARKER ||
					tokenName == XPathTokenName.LOCALNAME_CALL ||
					tokenName == XPathTokenName.QNAME_CALL || 
					tokenName == XPathTokenName.LEFTPAREN ) 
					result = true;
				return result;
			case STEP_EXPR :
				if( IsTokenForwardAxis(tokenName) ||
					IsTokenReverseAxis(tokenName) ||
					RecogniseNonTerminal(XPathNonTerminal.PRIMARY_EXPR) )
					result = true;
				return result;
			case PRIMARY_EXPR :
				if( RecogniseNonTerminal(XPathNonTerminal.LITERAL) ||
					RecogniseNonTerminal(XPathNonTerminal.FUNCTION_CALL) ||
					RecogniseNonTerminal(XPathNonTerminal.VARNAME) || 
					RecogniseNonTerminal(XPathNonTerminal.PARENTHESIZED_EXPR) )
					result = true;
				return result;
			case NAME_TEST :
				if( tokenName == XPathTokenName.LOCALNAME ||
					tokenName == XPathTokenName.QNAME ||
					tokenName == XPathTokenName.WILDCARD ||
					tokenName == XPathTokenName.LOCALNAME_WILDCARD ||
					tokenName == XPathTokenName.NAMESPACE_WILDCARD )
					result = true;
				return result;
			case NODE_TEST :
				if( tokenName == XPathTokenName.TEXT_NODE_TEST ||
					tokenName == XPathTokenName.COMMENT_NODE_TEST ||
					tokenName == XPathTokenName.ANY_NODE_TEST ||
					tokenName == XPathTokenName.PI_NODE_TEST )
					result = true;
				return result;
			case PREDICATES :
				if( tokenName == XPathTokenName.OPEN_BRACKET )
					result = true;
				return result;
			case LITERAL :
				if( IsTokenLiteral(tokenName) )
					result = true;
				return result;
			case VARNAME :
				if( tokenName == XPathTokenName.VARIABLE_MARKER )
					result = true;
				return result;
			case FUNCTION_CALL :
				if( tokenName == XPathTokenName.LOCALNAME_CALL ||
					tokenName == XPathTokenName.QNAME_CALL )
					result = true;
				return result;
			default: return result;
		}
	};
	
	public boolean IsTokenForwardAxis(XPathTokenName n){
		switch(n){
			case CHILD_AXIS: return true;
			case DESCENDANT_AXIS: return true;
			case ATTRIBUTE_AXIS: return true;
			case SELF_AXIS: return true;
			case DESCENDANT_OR_SELF_AXIS: return true;
			case FOLLOWING_SIBLING_AXIS: return true;
			case FOLLOWING_AXIS: return true;
			case NAMESPACE_AXIS:return true;
			default: return false;
		}
	};
	
	public boolean IsTokenReverseAxis(XPathTokenName n){
		switch(n){
			case PARENT_AXIS: return true;
			case ANCESTOR_AXIS: return true;
			case PRECEDING_AXIS: return true;
			case PRECEDING_SIBLING_AXIS: return true;
			case ANCESTOR_OR_SELF_AXIS: return true;
			default: return false;
		}
	};
	
	public boolean IsTokenLiteral(XPathTokenName n){
		switch(n){
			case STRING_LITERAL: return true;
			case INTEGER_LITERAL: return true;
			case DECIMAL_LITERAL: return true;
			case DOUBLE_LITERAL: return true;
			default: return false;
		}		
	};

	//Parse
	private ExprTreeNode XPath(){
		if (GetTokenName()!= XPathTokenName.ENDEXPR)
			return PathExpr();
		else
			return null;
	}
	
	private ExprTreeNode Expr(){
		ExprTreeNode node = new ExprTreeNode();
		if(RecogniseNonTerminal(XPathNonTerminal.PATH_EXPR)) {
			node.Kind = XPathSyntaxNodeKind.ETNK_PATH_EXPR;
			node.Children.add(PathExpr());
			return node;
		}
		else return null; //TODO: error
	}
	
	private ExprTreeNode PathExpr(){
		ExprTreeNode node = new ExprTreeNode();
		ExprTreeNode relexpr = new ExprTreeNode(); //GWT compile
		switch(GetTokenName()){
			case FORWARDSLASH:
	            if(MatchToken(XPathTokenName.FORWARDSLASH)){
	            	if (RecogniseNonTerminal(XPathNonTerminal.RELATIVE_PATH_EXPR)) {
						relexpr = RelativePathExpr();
	            	}
					else relexpr = null;
					node.Kind = XPathSyntaxNodeKind.ETNK_STEP;
					node.Children.add(relexpr);
					node.IsExprStart = true;
					return node;
	            }
			case DOUBLE_FORWARDSLASH:
				if(MatchToken(XPathTokenName.DOUBLE_FORWARDSLASH)){
					if (RecogniseNonTerminal(XPathNonTerminal.RELATIVE_PATH_EXPR)) {
						relexpr = RelativePathExpr();
					}
					else relexpr = null; //TODO: error
					node.Kind = XPathSyntaxNodeKind.ETNK_DOUBLE_STEP;
					node.Children.add(relexpr);
					node.IsExprStart = true;
					return node;
				}
			default:
				if(RecogniseNonTerminal(XPathNonTerminal.RELATIVE_PATH_EXPR)){
					node = RelativePathExpr();
					node.IsExprStart = true;
					return node;
				}
				else ;//TODO: error 
		}
		return null ;//TODO: error		
	}
	
	private ExprTreeNode RelativePathExpr(){
		ExprTreeNode node = new ExprTreeNode();
		XPathTokenName tokenName;
		if(RecogniseNonTerminal(XPathNonTerminal.STEP_EXPR)){
			node = StepExpr();
		}
		else return null; //TODO: error
	
		tokenName = GetTokenName();
		ExprTreeNode sibling = new ExprTreeNode(); //GWT Compile
		while( tokenName == XPathTokenName.FORWARDSLASH || 
			tokenName == XPathTokenName.DOUBLE_FORWARDSLASH){
			sibling = new ExprTreeNode(); //GWT Compile
			switch(tokenName){
				case FORWARDSLASH:
					MatchToken(XPathTokenName.FORWARDSLASH); 
					if (RecogniseNonTerminal(XPathNonTerminal.STEP_EXPR)){
						sibling.Kind = XPathSyntaxNodeKind.ETNK_STEP; 
						sibling.Children.add(StepExpr());
					}
					else sibling = null; //error
					break;
				case DOUBLE_FORWARDSLASH:
					MatchToken(XPathTokenName.DOUBLE_FORWARDSLASH);
					if (RecogniseNonTerminal(XPathNonTerminal.STEP_EXPR)){
						sibling.Kind = XPathSyntaxNodeKind.ETNK_DOUBLE_STEP; 
						sibling.Children.add(StepExpr());
					}
				else sibling = null; //error
				break;
			}
			if(sibling!=null)
				node.Siblings.add(sibling);
			tokenName = GetTokenName(); //udate token name
		}
		return node; 
	}
	
	private ExprTreeNode StepExpr(){
		ExprTreeNode node = new ExprTreeNode();
		XPathTokenName tokenName = GetTokenName();
		if(IsTokenForwardAxis(tokenName)){
			node.Token = this.CurrentToken;
			ExprTreeNode test = new ExprTreeNode(); //GWT Compile;
			if(this.ItToken.hasNext()){
				this.CurrentToken = (XPathTokenEntry) this.ItToken.next(); //not matching a specific token so just move forward
				if (RecogniseNonTerminal(XPathNonTerminal.NAME_TEST)){ 
					test = NameTest();
				}
				else if(RecogniseNonTerminal(XPathNonTerminal.NODE_TEST)){
					test = NodeTest();
				}
				else return null; // TODO: error
				node.Kind = XPathSyntaxNodeKind.ETNK_FORWARD_AXIS;
				node.Children.add(test);
			}
			else return null; // TODO: error
		}
		else if(IsTokenReverseAxis(tokenName)){
			node.Token = this.CurrentToken;
			ExprTreeNode test = new ExprTreeNode(); //GWT Compile;
			if(this.ItToken.hasNext()){
				this.CurrentToken = (XPathTokenEntry) this.ItToken.next(); //not matching a specific token so just move forward
				if (RecogniseNonTerminal(XPathNonTerminal.NAME_TEST)){ 
					test = NameTest();
				}
				else if(RecogniseNonTerminal(XPathNonTerminal.NODE_TEST)){
					test = NodeTest();
				}
				else return null; // TODO: error
				node.Kind = XPathSyntaxNodeKind.ETNK_REVERSE_AXIS;
				node.Children.add(test);
			}
			else return null; //TODO: error
		}
		else if(RecogniseNonTerminal(XPathNonTerminal.PRIMARY_EXPR)){
			node = PrimaryExpr();
		}
		else return null; //error
		
		ExprTreeNode sibling = new ExprTreeNode(); //GWT Compile;
		while(RecogniseNonTerminal(XPathNonTerminal.PREDICATES)){
			MatchToken(XPathTokenName.OPEN_BRACKET);
			sibling = Expr();
			if(sibling!=null) {
				sibling.Kind = XPathSyntaxNodeKind.ETNK_PREDICATE;
				node.Siblings.add(sibling);	
			}
			if(!MatchToken(XPathTokenName.CLOSE_BRACKET)) {
				//TODO: expr			
				//expressions in predicates not implemented :( e.g. [fn:position()=1]
				return null; 
			}
		}
		return node; 	
	}
	
	private ExprTreeNode ForwardStep(){  //TODO: 
		return null;
	}
	
	private ExprTreeNode ForwardAxis(){  //TODO: 
		return null;
	}
	
	private ExprTreeNode NodeTest(){
		ExprTreeNode node = new ExprTreeNode();
		node.Kind = XPathSyntaxNodeKind.ETNK_NODE_TEST;
		node.Token = this.CurrentToken;
		if(this.ItToken.hasNext()){
			this.ItToken.next();
		}
		return node;
	}
	
	private ExprTreeNode NameTest(){
		ExprTreeNode node = new ExprTreeNode();
		node.Kind = XPathSyntaxNodeKind.ETNK_NAME_TEST;
		node.Token = this.CurrentToken;
		if(this.ItToken.hasNext()){
			this.CurrentToken = (XPathTokenEntry) this.ItToken.next();
		}
		return node;
	}
	
	private ExprTreeNode KindTest(){ //TODO: 
		return null;
	}
	
	private ExprTreeNode PrimaryExpr(){
		ExprTreeNode node = new ExprTreeNode();
		XPathTokenName tokenName;
		if(RecogniseNonTerminal(XPathNonTerminal.LITERAL)){
			node.Kind = XPathSyntaxNodeKind.ETNK_LITERAL;
			node.Token = this.CurrentToken;
			if(this.ItToken.hasNext()){
				this.CurrentToken = (XPathTokenEntry) this.ItToken.next();
				return node;
			}
			else return null; //TODO: error
		}
		else if(RecogniseNonTerminal(XPathNonTerminal.VARNAME)){
			node.Kind = XPathSyntaxNodeKind.ETNK_VARIABLE;
			MatchToken(XPathTokenName.VARIABLE_MARKER);
			tokenName = GetTokenName();
			if( tokenName==XPathTokenName.LOCALNAME || 
				tokenName == XPathTokenName.QNAME) {
				node.Token = this.CurrentToken;
				if(this.ItToken.hasNext()){
					this.CurrentToken = (XPathTokenEntry) this.ItToken.next();
				}
				else return null; //TODO: error
			}
			else return null; //error;
			return node;
		}
		else if(RecogniseNonTerminal(XPathNonTerminal.FUNCTION_CALL)){
			node.Kind = XPathSyntaxNodeKind.ETNK_FUNCTION_CALL;
			node.Token = this.CurrentToken;
			if(this.ItToken.hasNext()){
				this.CurrentToken = (XPathTokenEntry) this.ItToken.next();
				tokenName = GetTokenName();
				while(tokenName!=XPathTokenName.RIGHTPAREN){
					node.Children.add(Expr());
					while(GetTokenName()==XPathTokenName.COMMA) {
						MatchToken(XPathTokenName.COMMA);
						node.Children.add(Expr());
					}
					tokenName = GetTokenName();
				}
				if(tokenName==XPathTokenName.RIGHTPAREN){
					if(this.ItToken.hasNext()){
						this.CurrentToken = (XPathTokenEntry) this.ItToken.next();					
					}
					else return null; //TODO: error
					return node;
				}
				else return null; //TODO: error
			}
			else return null; //TODO: error
		}
		else if(RecogniseNonTerminal(XPathNonTerminal.PARENTHESIZED_EXPR)){
			node.Kind = XPathSyntaxNodeKind.ETNK_EXPR_SEQUENCE;
			MatchToken(XPathTokenName.LEFTPAREN);
			tokenName = GetTokenName();
			while(tokenName!=XPathTokenName.RIGHTPAREN){
				node.Children.add(Expr());
				while(GetTokenName()==XPathTokenName.COMMA) {
					MatchToken(XPathTokenName.COMMA);
					node.Children.add(Expr());
				}
				tokenName = GetTokenName();
			}
			if(tokenName==XPathTokenName.RIGHTPAREN){
				if(this.ItToken.hasNext()){
					this.CurrentToken = (XPathTokenEntry) this.ItToken.next();
				}
				else return null; //TODO: error				
				return node;
			}
			else return null; //TODO: error
		}
		else return null; //TODO: error		
	}

	//Interpret
	private XPathSequence Evaluate(ExprTreeNode n, XPathSequence input){
		/**
	     * @gwt.typeArgs <com.artbase.xpath.client.ExprTreeNode>
	     */			
		Iterator itExprNode = (Iterator) (new Vector()).iterator(); //GWT Compile
		/**
	     * @gwt.typeArgs <com.artbase.xpath.client.XPathItem>
	     */			
		Iterator it = (Iterator) (new Vector()).iterator(); //GWT Compile
		
		XPathSequence result = new XPathSequence(); //return 
		XPathSequence seqFocus = new XPathSequence(); //focus
		XPathSequence tempSeq = new XPathSequence();
		XPathNode node = new XPathNode(); //GWT Compile
		XPathNode contextNode= new XPathNode(); //GWT Compile;
		XPathItem i = new XPathItem();	//GWT Compile;	
		XPathTokenName axis = XPathTokenName.ENDEXPR;
		
		switch(n.Kind){
			case ETNK_STEP : // "/"
				it = input.GetItems().iterator();
				while(it.hasNext()){
					i = (XPathItem) it.next();
					if(i.IsNode()){
						if(n.IsExprStart){
							tempSeq.GetItems().clear();
							//must append context item to a node so that child
							//nodes can be accessed. 
							//TODO: check operation of step axis on sequence items.
							node = new XPathNode();
							contextNode = (XPathNode)i;
							if(n.IsRoot) {
								contextNode.SetOwnerDocument(node);
								node._children.add(contextNode);
							}
							else {
								node._children.add(contextNode.GetOwnerDocument());
							}
							seqFocus.GetItems().add(node);
						}
						else seqFocus.GetItems().add((XPathItem)i);
						if(n.Children.size()==1) {//will be forward or reverse axis
							result.ConcatSequence(this.Evaluate((ExprTreeNode)n.Children.elementAt(0),seqFocus));
						}
						seqFocus.GetItems().clear();
					}
					else ; //TODO: error;
				}
				break; 
			case ETNK_DOUBLE_STEP :
				it = input.GetItems().iterator();
				i = null;
				while(it.hasNext()){
					i = (XPathItem) it.next();					
					if(i.IsNode()){
						// "//" at start of expression means.../descendant-or-self::node()
						if(n.IsExprStart){
							tempSeq.GetItems().clear();							
							node = new XPathNode();
							contextNode = (XPathNode) i;
							if(n.IsRoot) {
								contextNode.SetOwnerDocument(node);
								node._children.add(contextNode);
							}
							else {
								node._children.add(contextNode.GetOwnerDocument());
							}
							seqFocus.GetItems().add(node);
						}
						else seqFocus.GetItems().add(i);
						/**
					     * @gwt.typeArgs <com.artbase.xpath.client.XPathItem>
					     */	
						Iterator jt = (Iterator) seqFocus.GetItems().iterator();
						//gather descendants of context sequence
						XPathItem j = new XPathItem(); //GWT Compile
						while(jt.hasNext()){
							j = (XPathItem) jt.next();	
							node = (XPathNode) j;
							tempSeq.GetItems().add(j);
							tempSeq.GetItems().addAll(node.GetDescendants().GetItems());
						}
						seqFocus.GetItems().clear();

						//evaluate for each node in focus.
						jt = tempSeq.GetItems().iterator();
						while(jt.hasNext()){
							j = (XPathItem) jt.next();	
							seqFocus.GetItems().add(j);
							if(n.Children.size()==1){ //will be forward or reverse axis
								result.ConcatSequence(Evaluate((ExprTreeNode)n.Children.elementAt(0),seqFocus));
							}
							seqFocus.GetItems().clear();
						}
					}
					else ; //TODO: error;
				}
				result.SortItemsByDocOrder(); //TODO:
				break; 
			case ETNK_FORWARD_AXIS:
				axis = n.GetAxisName();
				if(n.IsRoot){
					node = new XPathNode();					
					//see ETNK_STEP for explanation
					it = input.GetItems().iterator();
					while(it.hasNext()){
						i = (XPathItem) it.next();	
						if(i.IsNode()){
							node._children.add((XPathNode) i);
						}
						else ; //TODO: error
					}
					seqFocus.GetItems().add(node);
				}
				else seqFocus = input;
				switch(((ExprTreeNode)n.Children.elementAt(0)).Kind){
					case ETNK_NAME_TEST :
						result = DoNameTest(seqFocus,axis,(ExprTreeNode)n.Children.elementAt(0));
						break;
					case ETNK_NODE_TEST : 
						result = DoNodeTest(seqFocus,axis,((ExprTreeNode)n.Children.elementAt(0)).Token.Token.Token.Name);
						break;
				}
				itExprNode = n.Siblings.iterator();
				ExprTreeNode sibling = new ExprTreeNode(); //GWT Compile
				while(itExprNode.hasNext()){
					sibling = (ExprTreeNode) itExprNode.next();
					result = this.Evaluate(sibling,result);
				}
				break;			
			case ETNK_REVERSE_AXIS :
				;
			case ETNK_NAME_TEST :
				;
			case ETNK_NODE_TEST :
				;
			case ETNK_LITERAL :
				;
			case ETNK_EXPR_SEQUENCE :
				;
			case ETNK_FUNCTION_CALL :
				it = input.GetItems().iterator();
				while(it.hasNext()){
					i = (XPathItem) it.next();
					seqFocus.GetItems().add(i);
					XPathFunction pFunc = new XPathFunction(); //GWT Compile
					XPathFuncArity pFuncArity = new XPathFuncArity(); //TODO: evaluation arguments here
					if(n.Token.Info.size()==2) //qname call
						pFunc = this.StatEnv.GetFunction(
							(String) ((XPathTokenInfo)n.Token.Info.elementAt(0)).Value,
							(String) ((XPathTokenInfo)n.Token.Info.elementAt(1)).Value,
							null);
					else if(n.Token.Info.size()==1) //localname call
						pFunc = this.StatEnv.GetFunction("",
							(String) ((XPathTokenInfo)n.Token.Info.elementAt(1)).Value,
							null);
					result.ConcatSequence(null);//((*this).*(pFunc.->PFunc))(seqFocus,pFunc)); //call function here
					if(seqFocus.GetItems().size()>0){
						seqFocus.GetItems().remove(seqFocus.GetItems().size()-1);
					}
				}
				break;
			case ETNK_PATH_EXPR :
				;
			case ETNK_VARIABLE :
				;
			case ETNK_PREDICATE :
				it = input.GetItems().iterator();
				while(it.hasNext()){
					i = (XPathItem) it.next();
					seqFocus.GetItems().add(i);
					if(n.Children.size()==1)
						if(Evaluate((ExprTreeNode)n.Children.elementAt(0),seqFocus).GetSize()!=0)
							result.AppendItem(i);
					if(seqFocus.GetItems().size()>0){					
						seqFocus.GetItems().remove(seqFocus.GetItems().size()-1);
					}
				}
				break;
		}
		return result;
	}
	
	private boolean isPatternBufferAPattern(Vector px, Vector py){
		/**
	     * @gwt.typeArgs <com.artbase.xpath.client.PatternItem>
	     */	
		Vector p1 = px;
		/**
	     * @gwt.typeArgs <java.lang.Integer>
	     */	
		Vector p2 = py;		
		
		if(p1.size()!=p2.size())return false;
		for(int i = 0; i<p1.size(); i++) {
			if(((PatternItem)p1.get(i)).Value!=((Integer)p2.get(i))) {
				return false; 
			}
		}
		return true;
	}
	
	// "/" at the start of an expression is an abreviation for 
	// fn:root(self::node()) ... this function returns the result
	// of this function.
	private XPathNode GetRootContextNode(){
		XPathItem item = (XPathItem) this.DynamicEnv.ContextItem.lastElement();
		if(item.IsNode()){
			XPathNode node = (XPathNode)item;
			if(node.GetOwnerDocument()!=null) return node;
			else return node.GetOwnerDocument();	
		}
		else return null; //error		
	};
	
	
	private XPathSequence DoNameTest(XPathSequence input, XPathTokenName axis, ExprTreeNode exprTreeNode){
		XPathSequence result = new XPathSequence();
		XPathNode node = new XPathNode();
		String name = "";
		Iterator it = input.GetItems().iterator();
		XPathItem i = new XPathItem(); //GWT Compile
		while(it.hasNext()){
			i = (XPathItem) it.next();
			if(i.IsNode()){
				node = (XPathNode) i;
				Iterator itNode = null;
				switch(axis) {
					case CHILD_AXIS:
						itNode = node._children.iterator();
						XPathNode child = new XPathNode(); //GWT Compile
						while(itNode.hasNext()){
							child = (XPathNode) itNode.next();
							switch(exprTreeNode.Token.Token.Token.Name){ //must adjust identifiers
								case LOCALNAME: 
									name = (String) ((XPathTokenInfo)exprTreeNode.Token.Info.lastElement()).Value;
									if(name.compareTo(child.GetLocalName())==0)
										result.GetItems().add(child);
									break;
								case QNAME: 
									break;
								case WILDCARD:
									if(child.GetNodeType()!=XPathNodeType.TEXT_NODE)
										result.GetItems().add(child);
									break;
								case LOCALNAME_WILDCARD:
									//TODO:
									break;
								case NAMESPACE_WILDCARD:
									//TODO:
									break;
							}
						}
						break;
					case ATTRIBUTE_AXIS: {
						itNode = node._attributes.iterator();
						XPathNode attr = new XPathNode(); //GWT Compile
						while(itNode.hasNext()){
							attr = (XPathNode) itNode.next();
							switch(exprTreeNode.Token.Token.Token.Name){ //TODO: must adjust identifiers
								case LOCALNAME: 
									name = (String) ((XPathTokenInfo)exprTreeNode.Token.Info.lastElement()).Value;
									if(name.compareTo(attr.GetLocalName())==0)
										result.GetItems().add(attr);
									break;
								case QNAME: 
									break;
								case WILDCARD: 
									result.GetItems().add(attr);
									break;
								case LOCALNAME_WILDCARD:
									//TODO: 
									break;
								case NAMESPACE_WILDCARD:
									//TODO:
									break;
							}
						}
						break;
					}
				}
			}
			else ; //TODO: error
		}
		return result;	
	}
	
	private XPathSequence DoNodeTest(XPathSequence input, XPathTokenName axis, XPathTokenName kind){
		XPathSequence result = new XPathSequence();
		XPathNode node = new XPathNode(); //GWT Compile
		/**
	     * @gwt.typeArgs <com.artbase.xpath.client.XPathItem>
	     */		
		Iterator it = (Iterator) input.GetItems().iterator();
		XPathItem i = new XPathItem(); //GWT Compile
		while(it.hasNext())
			i = (XPathItem) it.next();
			if(i.IsNode()) {
				node = (XPathNode) i;
				/**
			     * @gwt.typeArgs <com.artbase.xpath.client.XPathNode>
			     */					
				Iterator itNode = (Iterator) (new Vector()).iterator(); //GWT Compile
				switch(axis){
					case CHILD_AXIS:
						switch(kind){
							case ANY_NODE_TEST :
								itNode = node._children.iterator();
								XPathNode child = new XPathNode(); //GWT Compile
								while(itNode.hasNext()){
									child = (XPathNode) itNode.next();
									result.GetItems().add(child);
								}
								break;
							case TEXT_NODE_TEST :
								itNode = node._children.iterator();
								XPathNode text = new XPathNode(); //GWT Compile
								while(itNode.hasNext()){
									text = (XPathNode) itNode.next();
									if(text.GetNodeType()==XPathNodeType.TEXT_NODE)
										result.GetItems().add(text);
								}
								break;
							case COMMENT_NODE_TEST :
								break;
							case PI_NODE_TEST :
								break;
						}
					break;
				}
			}
		return result;	
	}
	
	//TODO below:
	
	//set variable $dot to node item in input sequence	
	private void SetDot(){
		this.DynamicEnv.SetVariable("fs:dot",this.DynamicEnv.ContextItem.lastElement());
//		if( this->Input->IsSingleton() && 
//			this->Input->GetItemAt(0)->IsNode())
//			this->DynamicEnv->Variables["fs:dot"]->Value.itemVal = this->Input->GetItemAt(0);
//		else
//			this->DynamicEnv->Variables["fs:dot"]->Value.itemVal = NULL;
//		this->DynamicEnv->Variables["fs:dot"]
	}

	//Function Implementations
	private XPathSequence FuncPosition(XPathSequence input, XPathFunction func){
		return new XPathSequence();
	}	

	
}
